/**
 * Copyright 2014 xiaojian
 *
 *
 * Create on 2014-8-14 上午11:15:01
 */
package xj.toolkit.handler.actor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

import xj.toolkit.bean.AbstractCommonBean;
import xj.toolkit.ebus.EventBus;
import xj.toolkit.ebus.actors.AbstractEventActor;
import xj.toolkit.handler.ReqHandler;
import xj.toolkit.util.ClosureEx;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;

/**
 * 事件对应到reqHander 对应关系。 
 * 
 * @author <a href="mailto:caoxiaojian@wasu.com>xiaojian.cao</a>
 * 
 */
public class ReqHandlerMultiEventActor extends AbstractEventActor implements
		BeanFactoryAware {

	private static final Logger logger = org.slf4j.LoggerFactory
			.getLogger(ReqHandlerMultiEventActor.class);

	private List<Runnable> dtors = new ArrayList<Runnable>();
	private Map<String, ClosureEx> closures = new HashMap<String, ClosureEx>();

	private BeanFactory beanFactory = null;

	private Map<String, String> eventHandlerBeanMap = Maps.newHashMap();

	/**
	 * 事件跟reqHander对应关系。${event} <-> ${reqHandler.beanname}
	 * 
	 * @param maps
	 */
	public void setEventHandlerBeanMap(Map<String, String> maps) {
		Preconditions.checkArgument(maps != null);
		this.eventHandlerBeanMap = maps;
	}

	/**
	 * 构建器。
	 * 
	 * @param ebus
	 *            事件
	 * @param name
	 *            Actor名称。
	 */
	public ReqHandlerMultiEventActor(EventBus ebus, String name) {
		super(ebus, name);
	}

	public Map<String, ClosureEx> getClosures() {
		return Collections.unmodifiableMap(closures);
	}

	public Map<String, String> getEventMapping() {
		Map<String, String> ret = new HashMap<String, String>();
		for (Map.Entry<String, ClosureEx> entry : this.closures.entrySet()) {
			ret.put(entry.getKey(), entry.getValue().toString());
		}

		return ret;
	}

	public void start() {

		this.closures.clear();

		for (Map.Entry<String, String> entry : eventHandlerBeanMap.entrySet()) {
			if (null != entry.getValue()) {
				ReqHandler<AbstractCommonBean> reqHandler = beanFactory.getBean(entry.getValue(),
						ReqHandler.class);
				if (reqHandler == null) {
					throw new IllegalArgumentException(
							"Cannot found bean with name[" + entry.getValue()
									+ "].");
				}
				this.closures.put(entry.getKey(), new ReqHandlerFunctor(
						reqHandler));

				logger.debug("Add event[" + entry.getKey()
						+ "] <-> reqHandler[" + entry.getValue() + "].");
			}
		}

		for (Map.Entry<String, ClosureEx> entry : this.closures.entrySet()) {
			String event = entry.getKey();
			dtors.add(registerObserver(event, entry.getValue()));
		}
	}

	public void destroy() {
		for (Runnable canceler : dtors) {
			try {
				canceler.run();
			} catch (Exception e) {
				logger.error("destroy:", e);
			}
		}
		dtors.clear();

		super.destroy();
	}

	/**
	 * 
	 * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org
	 *      .springframework.beans.factory.BeanFactory)
	 */
	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = beanFactory;
	}
}
